package j.util.jdbc;

import j.data.PagedData;
import j.util.New;
import j.util.StringUtils;
import j.util.TwoTuple;
import j.util.jdbc.simple.core.SimpleJdbcContext;
import j.util.jdbc.simple.core.operations.SimpleJdbcDeleteOperations;
import j.util.jdbc.simple.core.operations.SimpleJdbcInsertOperations;
import j.util.jdbc.simple.core.operations.SimpleJdbcQueryOperations;
import j.util.jdbc.simple.core.operations.SimpleJdbcUpdateOperations;
import j.util.jdbc.simple.core.support.SimpleJdbcUtils;

import javax.sql.DataSource;
import java.sql.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * User: jason
 * Date: 13-7-2 上午9:45
 */
public class TransactionalJdbcTemplate extends JdbcTemplate {

    private SimpleJdbcInsertOperations insert;
    //删除操作
    private SimpleJdbcDeleteOperations delete;
    //查询操作
    private SimpleJdbcQueryOperations query;
    //更新操作
    private SimpleJdbcUpdateOperations update;

    public TransactionalJdbcTemplate(DataSource ds) {
        this(ds, false);
    }

    public TransactionalJdbcTemplate(DataSource ds,boolean nowBeginTransactional) {
        super(ds);
        if(nowBeginTransactional){
            begin();
        }
        this.insert = SimpleJdbcContext.getInsertInstance();
        this.delete = SimpleJdbcContext.getDeleteInstance();
        this.query = SimpleJdbcContext.getQueryInstance();
        this.update = SimpleJdbcContext.getUpdateInstance();
    }

    private Connection conn;

    public Connection getConnection(){
        return this.conn;
    }

    public void begin(){
        log.debug("开启事务");
        try{
            conn = dataSource.getConnection();
            conn.setAutoCommit(false);
        }catch(SQLException e){
            log.error(String.format("开启事务时失败,异常信息:%s.",e.getMessage()));
            throw new RabbitJdbcException(String.format("TransactionalJdbcTemplate在获取数据库链接时出现异常,异常信息:%s.",e.getMessage()));
        }
    }

    public void close(){
        log.debug("关闭jdbc连接!");
        JdbcUtils.free(conn, null);
    }

    public void commit(){
        log.debug("提交事务");
        try{
            conn.commit();
        }catch(SQLException e){
            try{
                conn.rollback();
            }catch (SQLException e1){
                throw new RabbitJdbcException(String.format("TransactionalJdbcTemplate在回滚时务时出现异常,异常信息:%s.",e1.getMessage()));
            }
            throw new RabbitJdbcException(String.format("TransactionalJdbcTemplate在提交事务时异常(回滚事务成功),异常信息:%s.",e.getMessage()));
        }finally{
            JdbcUtils.free(conn, null);
        }
    }

    public void rollback(){
        log.debug("回滚事务");
        try{
            if(!conn.isClosed()){
                conn.rollback();
            }
        }catch(SQLException e){
            throw new RabbitJdbcException(String.format("TransactionalJdbcTemplate在回滚事务时异常,异常信息:%s.",e.getMessage()));
        }finally{
            JdbcUtils.free(conn, null);
        }
    }

    @Override
    public <T> T queryForDomain(String sql, RowMapper<T> rowMapper, Object... args) {
        log.debug(String.format("在事务中执行单数据查询sql语句：%s，参数：%s.",sql,getArgsInfo(args)));
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try{
            stmt = conn.prepareStatement(sql);
            JdbcUtils.setStatementArguments(stmt, args);
            rs = stmt.executeQuery();
            if(rs.next()){
                return rowMapper.mapRow(rs,0);
            }
        }catch(SQLException e){
            log.error(String.format("在事务中执行单数据查询sql语句：%s时出现异常：%s.", sql, e.getMessage()));
            throw new RabbitJdbcException(String.format("JdbcTemplate.queryForDomain在事务中执行单数据查询时出现异常：%s.",e.getMessage()));
        }finally{
            JdbcUtils.free(null, stmt, rs);
        }
        log.debug(String.format("在事务中执行单数据查询sql语句：%s时未获取到一条记录.",sql));
        return null;
    }

    @Override
    public void queryForDomain(String sql, ResultSetHandler resultSetHandler, Object... args) {
        log.debug(String.format("执行自定义ResultSetHandler的单数据查询sql语句：%s，参数：%s.",sql,getArgsInfo(args)));
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try{
            conn = dataSource.getConnection();
            stmt = conn.prepareStatement(sql);
            JdbcUtils.setStatementArguments(stmt, args);
            rs = stmt.executeQuery();
            if(rs.next()){
                resultSetHandler.doResultSet(rs);
            }
        }catch(SQLException e){
            log.error(String.format("执行自定义ResultSetHandler的单数据查询sql语句【%s】时出现异常：%s.", sql, e.getMessage()));
            throw new RabbitJdbcException(String.format("JdbcTemplate.queryForDomain执行单数据查询时出现异常：%s.",e.getMessage()));
        }finally{
            JdbcUtils.free(conn, stmt, rs);
        }
    }

    @Override
    public Map<String, Object> queryForMap(String sql, Object... args) {
        log.debug(String.format("在事务中执行单数据查询(Map)sql语句：%s，参数：%s.",sql,getArgsInfo(args)));
        Map<String,Object> map = New.map();
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try{
            stmt = conn.prepareStatement(sql);
            JdbcUtils.setStatementArguments(stmt, args);
            rs = stmt.executeQuery();
            if(rs.next()){
                ResultSetMetaData rsmd = rs.getMetaData();
                int columnCount = rsmd.getColumnCount();
                for (int i = 1; i <= columnCount; i++) {
                    String key = rsmd.getColumnName(i);
                    Object obj = JdbcUtils.getResultSetValue(rs, i);
                    map.put(key, obj);
                }
            }
        }catch(SQLException e){
            log.error(String.format("在事务中执行单数据查询(Map)sql语句：%s时出现异常：%s.", sql, e.getMessage()));
            throw new RabbitJdbcException(String.format("JdbcTemplate.queryForDomain在事务中执行单数据查询时出现异常：%s.",e.getMessage()));
        }finally{
            JdbcUtils.free(null, stmt, rs);
        }
        return map;
    }

    @Override
    public List<Map<String, Object>> queryForListMap(String sql, Object... args) {
        log.debug(String.format("在事务中执行数据集查询(List<Map>)sql语句：%s，参数：%s.",sql,getArgsInfo(args)));
        List<Map<String,Object>> list = New.list();
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try{
            stmt = conn.prepareStatement(sql);
            JdbcUtils.setStatementArguments(stmt, args);
            rs = stmt.executeQuery();
            ResultSetMetaData rsmd;
            Map<String,Object> map;
            String key;
            Object objV;
            int columnCount = 0,i;
            while(rs.next()){
                rsmd = rs.getMetaData();
                if(columnCount==0){
                    columnCount = rsmd.getColumnCount();
                }
                map = New.map();
                for (i = 1; i <= columnCount; i++) {
                    key = rsmd.getColumnName(i);
                    objV = JdbcUtils.getResultSetValue(rs, i);
                    map.put(key, objV);
                }
                list.add(map);
            }
        }catch(SQLException e){
            log.error(String.format("在事务中执行数据集查询(List<Map>)sql语句：%s时出现异常：%s.", sql, e.getMessage()));
            throw new RabbitJdbcException(String.format("JdbcTemplate.queryForListMap在事务中执行数据集(List<Map>)查询时出现异常：%s.",e.getMessage()));
        }finally{
            JdbcUtils.free(null, stmt, rs);
        }
        return list;
    }

    @Override
    public <T> PagedData<List<T>> queryForPaging(String sql, RowMapper<T> rowMapper, int pageIndex, int pageSize, Object... args) {
        log.debug(String.format("在事务中以分页形式查询记录集,当前页:%s,页大小:%s,sql:%s,参数:%s.",pageIndex,pageSize,sql,getArgsInfo(args)));
        if(pageIndex<=0){
            pageIndex = 1;
        }
        if(pageSize<=0){
            pageSize = DEFAULT_PAGE_SIZE;
        }
        Object[] _args = new Object[args.length+2];
        int i;
        for(i=0;i<args.length;i++){
            _args[i] = args[i];
        }
        String _sql = null;
        DatabaseType dbType = JdbcPlatform.getDatabaseType(dataSource);
        if(dbType.equals(DatabaseType.MYSQL)){
            //mysql数据库
            _args[i++] = (pageIndex-1)*pageSize;
            _args[i] = pageSize;
            _sql = String.format(JdbcTemplate.MYSQL_PAGING_TEMPLATE,sql);
        }else if(dbType.equals(DatabaseType.MSSQL)){
            _sql = String.format(JdbcTemplate.MSSQL_PAGING_TEMPLATE,sql);
            _args[i++] = (pageIndex-1)*pageSize;
            _args[i] = pageSize;
        }else if(dbType.equals(DatabaseType.ORACLE)){
            _sql = String.format(JdbcTemplate.ORACLE_PAGING_TEMPLATE,sql);
            _args[i++] = (pageIndex-1)*pageSize+1;
            _args[i] = pageSize;
        }
        if(StringUtils.isNullOrEmpty(_sql)){
            throw new RabbitJdbcException("没有获取到当前数据库管理系统的类型!");
        }
        int totalList = 0;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try{
            //先计算总记录数
            boolean isComplex = sql.contains("@@");
            stmt = conn.prepareStatement(JdbcUtils.formatSqlToCount(sql,isComplex));
            JdbcUtils.setStatementArguments(stmt, args);
            rs = stmt.executeQuery();
            if(rs.next()){
                totalList = rs.getInt(1);
            }
            rs.close();stmt.close();
            if(isComplex){
                _sql = _sql.replaceFirst("@@","");
            }
            stmt = conn.prepareStatement(_sql);
            JdbcUtils.setStatementArguments(stmt, _args);
            rs = stmt.executeQuery();
            List<T> list = New.list();
            i = 0;
            while(rs.next()){
                list.add(rowMapper.mapRow(rs,i++));
            }
            return new PagedData<List<T>>(pageIndex,pageSize,totalList,list);
        }catch(SQLException e){
            log.error(String.format("在事务中以分页形式查询记录集时出现异常：%s,sql语句【%s】.", sql, e.getMessage()));
            throw new RabbitJdbcException(String.format("JdbcTemplate.queryForList在事务中执行数据查询时出现异常：%s.",e.getMessage()));
        }finally{
            JdbcUtils.free(null, stmt, rs);
        }
    }

    @Override
    public <T> List<T> queryForList(String sql, RowMapper<T> rowMapper, Object... args) {
        log.debug(String.format("在事务中执行自定义RowMapper的记录集查询sql语句：%s，参数：%s.",sql,getArgsInfo(args)));
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try{
            stmt = conn.prepareStatement(sql);
            JdbcUtils.setStatementArguments(stmt, args);
            rs = stmt.executeQuery();
            List<T> list = New.list();
            int index = 0;
            while(rs.next()){
                list.add(rowMapper.mapRow(rs,index++));
            }
            return list;
        }catch(SQLException e){
            log.error(String.format("在事务中执行自定义RowMapper的记录集查询sql语句【%s】时出现异常：%s.", sql, e.getMessage()));
            throw new RabbitJdbcException(String.format("JdbcTemplate.queryForList在事务中执行数据查询时出现异常：%s.",e.getMessage()));
        }finally{
            JdbcUtils.free(null, stmt, rs);
        }
    }

    @Override
    public void queryForList(String sql, ResultSetHandler resultSetHandler, Object... args) {
        log.debug(String.format("在事务中执行自定义ResultSetHandler的记录集查询sql语句：%s，参数：%s.",sql,getArgsInfo(args)));
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try{
            stmt = conn.prepareStatement(sql);
            JdbcUtils.setStatementArguments(stmt, args);
            rs = stmt.executeQuery();
            while(rs.next()){
                resultSetHandler.doResultSet(rs);
            }
        }catch(SQLException e){
            log.error(String.format("在事务中执行自定义ResultSetHandler的记录集查询sql语句【%s】时出现异常：%s.", sql, e.getMessage()));
            throw new RabbitJdbcException(String.format("JdbcTemplate.queryForList(自处理结集)在事务中执行数据查询时出现异常：%s.",e.getMessage()));
        }finally{
            JdbcUtils.free(null, stmt, rs);
        }
    }

    @Override
    public int queryForInt(String sql, Object... args) {
        log.debug(String.format("在事务中执行整形数据sql语句：%s，参数：%s.",sql,getArgsInfo(args)));
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try{
            stmt = conn.prepareStatement(sql);
            JdbcUtils.setStatementArguments(stmt, args);
            rs = stmt.executeQuery();
            if(rs.next()){
                return rs.getInt(1);
            }else{
                throw new RabbitJdbcException(String.format("在事务中queryForInt没有查询到任何数据"));
            }
        }catch(SQLException e){
            log.error(String.format("在事务中执行整形数据sql语句：%s时出现异常：%s.", sql, e.getMessage()));
            throw new RabbitJdbcException(String.format("JdbcTemplate.queryForInt在事务中执行整形数据查询时出现异常：%s.",e.getMessage()));
        }finally{
            JdbcUtils.free(null, stmt, rs);
        }
    }

    @Override
    public Object queryForObject(String sql, Object... args) {
        log.debug(String.format("在事务中执行单结果sql语句：%s，参数：%s.",sql,getArgsInfo(args)));
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try{
            stmt = conn.prepareStatement(sql);
            JdbcUtils.setStatementArguments(stmt, args);
            rs = stmt.executeQuery();
            if(rs.next()){
                return rs.getObject(1);
            }
        }catch(SQLException e){
            log.error(String.format("在事务中执行单结果sql语句：%s时出现异常：%s.",sql,e.getMessage()));
            throw new RabbitJdbcException(String.format("JdbcTemplate.queryForInt在事务中执行单结果查询时出现异常：%s.",e.getMessage()));
        }finally{
            JdbcUtils.free(null, stmt, rs);
        }
        return null;
    }

    @Override
    public int execute(String sql, Object... args) {
        log.debug(String.format("在事务中执行单条操作sql语句：%s，参数：%s.",sql,getArgsInfo(args)));
        PreparedStatement stmt = null;
        try{
            stmt = conn.prepareStatement(sql);
            JdbcUtils.setStatementArguments(stmt, args);
            return stmt.executeUpdate();
        }catch(SQLException e){
            log.error(String.format("在事务中执行单条操作sql[%s]语句时异常：%s.", sql, e.getMessage()));
            throw new RabbitJdbcException(String.format("在事务中执行单条操作sql[%s]语句时异常：%s.",sql,e.getMessage()));
        }finally {
            JdbcUtils.free(null, stmt);
        }
    }

    @Override
    public int[] executeBatch(String sql, List<Object[]> argsList) {
        log.debug(String.format("在事务中执行批量操作sql语句：%s，参数：%s.",sql,getListArgsInfo(argsList)));
        PreparedStatement stmt = null;
        try{
            stmt = conn.prepareStatement(sql);
            if(null!=argsList && argsList.size()>0){
                for(Object[] args : argsList){
                    JdbcUtils.setStatementArguments(stmt, args);
                    stmt.addBatch();
                }
                return stmt.executeBatch();
            }
            log.debug(String.format("在事务中批量操作sql[%s]语句没有指定任何参数,没有执行.", sql));
            return new int[0];
        }catch(SQLException e){
            log.error(String.format("在事务中执行批量操作sql[%s]语句时异常：%s.", sql, e.getMessage()));
            throw new RabbitJdbcException(String.format("在事务中执行批量操作sql[%s]语句时异常：%s.",sql,e.getMessage()));
        }finally {
            JdbcUtils.free(null, stmt);
        }
    }

    @Override
    public int executeInsert(String tableName, Map<String, Object> columnValuesMap) {
        //生成sql语句,在生成语句的同时确定参数位置
        StringBuilder sql = new StringBuilder("INSERT INTO ");
        sql.append(tableName).append("(");
        Object[] args = new Object[columnValuesMap.size()];
        int i = 0;
        for(Map.Entry<String,Object> entry : columnValuesMap.entrySet()){
            if(i>0){
                sql.append(",");
            }
            sql.append(entry.getKey());
            args[i++] = entry.getValue();
        }
        sql.append(") VALUES (").append(StringUtils.leftPad("", (i - 1) * 2, "?,")).append("?)");
        return execute(sql.toString(),args);
    }

    @Override
    public int executeUpdate(String tableName, Map<String, Object> updatedColumnValuesMap, String whereSql, Object... whereArgs) {
        if(StringUtils.isNullOrEmpty(whereSql) || whereArgs.length == 0){
            throw new RabbitJdbcException("JdbcTemplate.executeUpdate功能集必须指定sql语句的where部分,请确认.");
        }
        Object[] args = new Object[updatedColumnValuesMap.size()+whereArgs.length];
        StringBuilder sql = new StringBuilder("UPDATE ");
        sql.append(tableName).append(" SET ");
        int i = 0;
        for(Map.Entry<String,Object> entry : updatedColumnValuesMap.entrySet()){
            if(i>0){
                sql.append(",");
            }
            sql.append(String.format("%s = ?",entry.getKey()));
            args[i++] = entry.getValue();
        }
        sql.append(" WHERE ").append(whereSql);
        //再将where部分的参数增加到参数列表中
        for(Object o : whereArgs){
            args[i] = o;
            i++;
        }
        return execute(sql.toString(),args);
    }

    @Override
    public int insert(Object object) {
        try {
            return insert.insert(conn, object.getClass(), SimpleJdbcUtils.fromEntityToMap(object));
        } catch (SQLException e) {
            String msg = String.format("在整条中执行insert[%s]操作时出错,异常:%s.",object.getClass().getName(),e.getMessage());
            log.error(msg);
            throw new RabbitJdbcException(msg);
        }
    }

    @Override
    public Number insertAndReturnKey(Object object) {
        Class clazz = object.getClass();
        try{
            return insert.insertAndReturnKey(conn, clazz, SimpleJdbcUtils.fromEntityToMap(object));
        }catch(SQLException e){
            String msg = String.format("在事务中执行INSERTANDRETURNKEY OBJECT[%s]时异常：%s.", clazz.getName(), e.getMessage());
            log.error(msg);
            throw new RabbitJdbcException(msg);
        }
    }

    @Override
    public int[] insertBatch(Class<?> clazz, List<?> objects) {
        if(null == objects || objects.size() == 0){
            return new int[0];
        }
        Map<String, Object>[] args = new HashMap[objects.size()];
        for(int i=0;i<objects.size();i++){
            args[i] = SimpleJdbcUtils.fromEntityToMap(objects.get(i));
        }
        try{
            return insert.insertBatch(conn, clazz, args);
        }catch(SQLException e){
            String msg = String.format("在事务中执行INSERT BATCH OBJECT[%s]时异常：%s.", clazz.getName(), e.getMessage());
            log.error(msg);
            throw new RabbitJdbcException(msg);
        }
    }

    @Override
    public <T> int delete(T t) {
        Map<String,Object> args = SimpleJdbcUtils.fromEntityToMapWithPk(t);
        return this.delete(t.getClass(), args);
    }

    @Override
    public <T> int[] deleteBatch(List<T> list) {
        if(null == list || list.size() == 0){
            throw new RuntimeException("delete batch must have at least one entity.");
        }
        List<Map<String,Object>> _list = New.list(list.size());
        Class clazz = list.get(0).getClass();
        for(T t : list){
            _list.add(SimpleJdbcUtils.fromEntityToMap(t));
        }
        try{
            return delete.deleteBatch(conn,clazz, _list);
        }catch(SQLException e){
            String msg = String.format("在事务中执行DELETE BATCH OBJECT[%s]时异常：%s.", clazz.getName(), e.getMessage());
            log.error(msg);
            throw new RabbitJdbcException(msg);
        }
    }

    @Override
    public <T> int delete(Class<T> clazz, Map<String, Object> args) {
        //将以实体属性名字为key的map转换以数据库中字段为名字的key
        Map<String,String> entityAttributeColumnMap = SimpleJdbcContext.getSQLData(clazz).getTmd().getEntityAttributeColumnMap();
        Map<String,Object> _args = SimpleJdbcUtils.toDbColumnKeyMap(entityAttributeColumnMap, args);
        try{
            return delete.delete(conn, clazz, _args);
        }catch(SQLException e){
            String msg = String.format("在事务中执行DELETE OBJECT[%s]时异常：%s.", clazz.getName(), e.getMessage());
            log.error(msg);
            throw new RabbitJdbcException(msg);
        }
    }

    @Override
    public <T> int deleteByCW(Class<T> clazz, Map<String, Object> args) {
        if(null==args || args.size() == 0){
            throw new RuntimeException("deleteByCW must to specify argument at least one,key is entity attribute's name.");
        }
        try{
            return delete.deleteByCW(conn, clazz, args);
        }catch(SQLException e){
            String msg = String.format("在事务中执行deleteByCW OBJECT[%s]时异常：%s.", clazz.getName(), e.getMessage());
            log.error(msg);
            throw new RabbitJdbcException(msg);
        }
    }

    @Override
    public <T> T findByPk(Class<T> requiredType, Map<String, Object> args) {
        try{
            return query.findByPk(conn, requiredType, args);
        }catch(SQLException e){
            String msg = String.format("在事务中执行findByPk[%s]时异常：%s.", requiredType.getName(), e.getMessage());
            log.error(msg);
            throw new RabbitJdbcException(msg);
        }
    }

    @Override
    public <T> List<T> queryForList(Class<T> requiredType, Map<String, Object> args, Map<String, String> orders) {
        try{
            return query.queryList(conn, requiredType, args, orders);
        }catch(SQLException e){
            String msg = String.format("在事务中执行queryList[%s]时异常：%s.", requiredType.getName(), e.getMessage());
            log.error(msg);
            throw new RabbitJdbcException(msg);
        }
    }

    @Override
    public PagedData<List<Map<String, Object>>> queryForPaging(String sql, int pageIndex, int pageSize, Object... args) {
        log.debug(String.format("在QueryJdbcTemplate中执行以ListMap封装数据的分页方法，sql:%s，参数：%s.",sql,getArgsInfo(args)));
        TwoTuple<String,Object[]> pagingArgs = getCorrectGetPagingSql(sql,pageIndex,pageSize,args);
        if(StringUtils.isNullOrEmpty(pagingArgs.first)){
            throw new RabbitJdbcException("没有获取到当前数据库管理系统的类型!");
        }
        String pagingSql = pagingArgs.first;
        int totalList = 0;
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try{
            conn = dataSource.getConnection();
            //先计算总记录数
            boolean isComplex = sql.contains("@@");
            stmt = conn.prepareStatement(JdbcUtils.formatSqlToCount(sql,isComplex));
            JdbcUtils.setStatementArguments(stmt, args);
            rs = stmt.executeQuery();
            if(rs.next()){
                totalList = rs.getInt(1);
            }
            rs.close();stmt.close();
            if(isComplex){
                pagingSql = pagingSql.replaceFirst("@@","");
            }
            stmt = conn.prepareStatement(pagingSql);
            JdbcUtils.setStatementArguments(stmt, pagingArgs.second);
            rs = stmt.executeQuery();
            List<Map<String,Object>> listMap = New.list();
            ResultSetMetaData rsmd;
            Map<String,Object> map;
            String key;
            Object objV;
            int columnCount = 0,i;
            while(rs.next()){
                rsmd = rs.getMetaData();
                if(columnCount==0){
                    columnCount = rsmd.getColumnCount();
                }
                map = New.map();
                for (i = 1; i <= columnCount; i++) {
                    key = rsmd.getColumnName(i);
                    objV = JdbcUtils.getResultSetValue(rs, i);
                    map.put(key, objV);
                }
                listMap.add(map);
            }
            return new PagedData<List<Map<String,Object>>>(pageIndex,pageSize,totalList,listMap);
        }catch(SQLException e){
            throw new RabbitJdbcException(String.format("在QueryJdbcTemplate中执行以ListMap封装数据的分页方法时出现异常：%s.",e.getMessage()));
        }finally{
            JdbcUtils.free(conn, stmt, rs);
        }
    }

    @Override
    public <T> PagedData<List<T>> queryForPaging(Class<T> requiredType, int pageIndex, int pageSize, Map<String, Object> args, Map<String, String> orders) {
        try{
            return query.queryList(conn,requiredType, pageIndex, pageSize, args, orders);
        }catch(SQLException e){
            String msg = String.format("在事务中执行queryList[%s]时异常：%s.", requiredType.getName(), e.getMessage());
            log.error(msg);
            throw new RabbitJdbcException(msg);
        }
    }

    @Override
    public <T> int update(Class<T> clazz, Map<String, Object> updatedData) {
        //将map中的key转换为以数据库字段为名称的map
        Map<String,Object> args = SimpleJdbcUtils.toDbColumnKeyMap(
                SimpleJdbcContext.getSQLData(clazz).getTmd().getEntityAttributeColumnMap(), updatedData);
        try{
            return update.update(conn,clazz,args);
        }catch(SQLException e){
            String msg = String.format("在事务中执行update map[%s]时异常：%s.", clazz.getName(), e.getMessage());
            log.error(msg);
            throw new RabbitJdbcException(msg);
        }
    }

    @Override
    public <T> int update(T t) {
        Class clazz = t.getClass();
        Map<String,Object> updatedData = SimpleJdbcUtils.fromEntityToMap(t);
        try{
            return update.update(conn,clazz,updatedData);
        }catch(SQLException e){
            String msg = String.format("在事务中执行update object[%s]时异常：%s.", clazz.getName(), e.getMessage());
            log.error(msg);
            e.printStackTrace();
            throw new RabbitJdbcException(msg);
        }
    }

    @Override
    public <T> int update(Class<T> clazz, Map<String, Object> updatedData, Map<String, Object> where) {
        //将updatedData的key转换为数据库字段名称
        Map<String,Object> args = SimpleJdbcUtils.toDbColumnKeyMap(SimpleJdbcContext.getSQLData(clazz).getTmd().getEntityAttributeColumnMap(), updatedData);
        try{
            return update.update(conn,clazz,args,where);
        }catch(SQLException e){
            String msg = String.format("在事务中执行update map with whereMap[%s]时异常：%s.", clazz.getName(), e.getMessage());
            log.error(msg);
            throw new RabbitJdbcException(msg);
        }
    }

    @Override
    public <T> int[] updateBatch(Class<T> clazz, List<T> list) {
        if(null == list || list.size()==0){
            return new int[0];
        }
        List<Map<String,Object>> _list = New.list(list.size());
        for(int i=0;i<list.size();i++){
            _list.add(SimpleJdbcUtils.fromEntityToMap(list.get(i)));
        }
        try{
            return update.updateBatch(conn, clazz, _list);
        }catch(SQLException e){
            String msg = String.format("在事务中执行updateBatch[%s]时异常：%s.", clazz.getName(), e.getMessage());
            log.error(msg);
            throw new RabbitJdbcException(msg);
        }
    }
}
